package com.hisense.ovcloud.warehouse.config.webclient;

import io.netty.handler.ssl.SslContextBuilder;
import io.netty.handler.ssl.util.InsecureTrustManagerFactory;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.http.client.reactive.ReactorClientHttpConnector;
import org.springframework.web.reactive.function.client.ExchangeStrategies;
import org.springframework.web.reactive.function.client.WebClient;
import reactor.netty.http.client.HttpClient;
import reactor.netty.resources.ConnectionProvider;

import java.time.Duration;
import java.util.UUID;

@Configuration("DomainServiceWebClientConfig")
public class WebClientConfig {
    private final WebClientProperties properties;

    public WebClientConfig(@Qualifier("domainServiceWebClientProperties") WebClientProperties properties) {
        this.properties = properties;
    }

    @Bean("domainServiceWebClient")
    public WebClient webClient(){
        final ExchangeStrategies strategies = ExchangeStrategies.builder()
                .codecs(codecs -> codecs.defaultCodecs().maxInMemorySize(properties.getMaxInMemorySize()))
                .build();
        return WebClient.builder().clientConnector(new ReactorClientHttpConnector(HttpClient
                .create(
                        ConnectionProvider.builder(UUID.randomUUID().toString())
                                .maxConnections(properties.getMaxConnections())
                                .maxIdleTime(Duration.ofSeconds(properties.getMaxIdleTime()))
                                .maxLifeTime(Duration.ofSeconds(properties.getMaxLifeTime()))
                                .pendingAcquireTimeout(Duration.ofSeconds(properties.getPendingAcquireTimeout()))
                                .pendingAcquireMaxCount(properties.getPendingAcquireMaxCount())
                                .evictInBackground(Duration.ofSeconds(properties.getEvictInBackground())).build()
                )
                .secure(sslContextSpec -> sslContextSpec.sslContext(SslContextBuilder.forClient().trustManager(InsecureTrustManagerFactory.INSTANCE)))
                .responseTimeout(Duration.ofSeconds(properties.getReadTimeout()))
                .compress(properties.isCompressionEnabled())
                .followRedirect(true)

        ))
                .exchangeStrategies(strategies)
                .defaultHeader(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE).build();
    }
}
